/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package familytree.persistencia.dao.hibernate;

import familytree.persistencia.dao.AlbumDAO;
import familytree.persistencia.dao.ArbolDAO;

import familytree.persistencia.dao.NodoDAO;
import familytree.persistencia.dao.ParejaDAO;
import familytree.persistencia.dao.UsuarioDAO;
import familytree.persistencia.pojos.Album;
import familytree.persistencia.pojos.Arbol;
import familytree.persistencia.pojos.Nodo;
import familytree.persistencia.pojos.Pareja;
import familytree.persistencia.pojos.Usuario;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;


import java.util.Set;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Transaction;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;

/**
 *
 * @author Antonio
 */
public class HibernateArbolDAO extends HibernateGenericDAO<Arbol, String>
        implements ArbolDAO {

    public void addComponentes(List<Nodo> lista) {
        Transaction tx = super.getSession().beginTransaction();
        try {
            NodoDAO nodoDAOHibernate = new HibernateNodoDAO();
            for (Nodo nodo : lista) {
                nodoDAOHibernate.makePersistent(nodo);
            }
        } catch (HibernateException e) {
            tx.rollback();
        }
    }

    public void anadirMadre(Pareja p, Nodo madre, Nodo hijo) {
        Transaction tx = super.getSession().beginTransaction();
        try {
            NodoDAO nodoDAOHibernate = new HibernateNodoDAO();
            ParejaDAO parejaDAOHibernate = new HibernateParejaDAO();
            nodoDAOHibernate.makePersistent(madre);
            nodoDAOHibernate.makePersistent(hijo);
            parejaDAOHibernate.makePersistent(p);
            tx.commit();
        } catch (HibernateException e) {
            tx.rollback();
        }
    }

    public void anadirPadre(Pareja p, Nodo padre, Nodo hijo) {
        Transaction tx = super.getSession().beginTransaction();
        try {
            NodoDAO nodoDAOHibernate = new HibernateNodoDAO();
            ParejaDAO parejaDAOHibernate = new HibernateParejaDAO();
            nodoDAOHibernate.makePersistent(padre);
            nodoDAOHibernate.makePersistent(hijo);
            parejaDAOHibernate.makePersistent(p);
            tx.commit();
        } catch (HibernateException e) {
            tx.rollback();
        }
    }

    public void anadirPareja(Nodo nodo, Nodo conyuje) {
        Transaction tx = super.getSession().beginTransaction();
        try {
        //Recupero el nodo existente en la base de datos
        NodoDAO nodoDAOHibernate = new HibernateNodoDAO();
        Query query = getSession().createQuery("FROM Nodo WHERE idNodo=:idNodo");
        query.setParameter("idNodo", nodo.getIdNodo());
        List<Nodo> lista = query.list();
        Nodo n = lista.get(0);

        //Ahora construyo la nueva pareja
        Pareja pareja = new Pareja();
        if (n.getSexo().equals("femenino")) {
            conyuje.setSexo("masculino");
            pareja.setComponente1(conyuje);
            pareja.setComponente2(n);

        } else {
            conyuje.setSexo("femenino");
            pareja.setComponente2(conyuje);
            pareja.setComponente1(n);
        }

        n.addPareja(pareja);
        conyuje.addPareja(pareja);
        conyuje.setArbol(n.getArbol());

        //Hago la transaccion
        
            ParejaDAO parejaDAOHibernate = new HibernateParejaDAO();
            parejaDAOHibernate.makePersistent(pareja);
            nodoDAOHibernate.makePersistent(conyuje);
            nodoDAOHibernate.makePersistent(n);

            tx.commit();
        } catch (HibernateException e) {
            tx.rollback();
        }
    }

    public Nodo anadirHijo(Nodo nodoActual, String idPareja, Nodo h) {
        Transaction tx = super.getSession().beginTransaction();
        //  String queryString = "SELECT p.* FROM pareja p";
        //  queryString += " WHERE p.idPAREJA = :idPareja ";
        Nodo hijo = null;
        try {

            NodoDAO nodoDao = new HibernateNodoDAO();
            ParejaDAO parejaDao = new HibernateParejaDAO();
           
            Query query = getSession().createQuery("FROM Pareja WHERE idPareja=:idPareja");
            query.setParameter("idPareja", idPareja);
            List<Pareja> lista = new ArrayList<Pareja>();
            lista=query.list();
            Pareja p = lista.get(0);
            h.setPadres(p);
            h.setArbol(nodoActual.getArbol());
            p.addHijos(h);

            Set<Pareja> parejas = new HashSet<Pareja>();
            for(Pareja par:(Set<Pareja>)parejas){
                parejas.add(par);
            }
            
            parejas.addAll(nodoActual.getParejasComoComponenteDos());

            hijo = nodoDao.makePersistent(h);
            Pareja pareja = parejaDao.makePersistent(p);

            tx.commit();
        } catch (HibernateException e) {
            tx.rollback();
        }
        return hijo;
    }

    public Usuario iniciarFamila(Arbol arbol, Nodo nodoHijo, Nodo nodoPadre, Nodo nodoMadre, Usuario usuario, Album album) {

        Pareja pareja;
        Transaction tx = getSession().beginTransaction();


        try {
            //Se inserta primero el árbol
            ArbolDAO arbolDAO = new HibernateArbolDAO();
            UsuarioDAO usuarioDAO = new HibernateUsuarioDAO();
            AlbumDAO albumDAO = new HibernateAlbumDAO();
            usuario = usuarioDAO.makePersistent(usuario);
            arbol = arbolDAO.makePersistent(arbol);

            album.setUsuario(usuario);
            albumDAO.makePersistent(album);

            //Se crea la pareja
            pareja = new Pareja();

            //se añade el padre
            pareja.setComponente1(nodoPadre);
            nodoPadre.addPareja(pareja);
            arbol.addNodo(nodoPadre);

            //se añade la madre
            pareja.setComponente2(nodoMadre);
            nodoMadre.addPareja(pareja);
            arbol.addNodo(nodoMadre);

            //se añade el hijo al arbol, a la pareja y a los usuarios
            arbol.addNodo(nodoHijo);
            nodoHijo.setUsuario(usuario);
            usuario.setNodo(nodoHijo);

            pareja.addHijos(nodoHijo);




            tx.commit();

        } catch (HibernateException he) {
            tx.rollback();
            usuario = null;
        }

        //Cerramos la sesión

        return usuario;
    }

    public List<Nodo> findNodosByIdArbol(String idArbol) {
        Transaction transaction = getSession().beginTransaction();
        List<Nodo> lista = new ArrayList<Nodo>();
        try{              
              Query query = getSession().createQuery("from Nodo where arbol.idArbol = :idArbol");
              query.setString("idArbol", idArbol);
              lista = query.list();
              transaction.commit();
        }
        catch(HibernateException he){
            System.out.print(he);
        }
        return lista;
        
    }

    public List<Nodo> findNodosByCompleteName(String nombre, String idArbol) {
        Transaction transaction = getSession().beginTransaction();
       List<Nodo> lista = new ArrayList<Nodo>();
       try{              
              SQLQuery query = getSession().createSQLQuery("SELECT n.* FROM nodo n WHERE n.idArbol = :idArbol AND Concat(n.nombre, ' ',n.primerapellido,' ',n.segundoapellido) = :nombreCompleto");
              query.addEntity(Nodo.class);
              query.setString("idArbol", idArbol);
              query.setString("nombreCompleto", nombre);
              lista = query.list();
              transaction.commit();
        }
        catch(HibernateException he){
            System.out.print(he);
        }
        return lista;
    }
}
